package org.richin.io.util;

import java.io.*;
import java.net.URL;
import java.nio.*;
import java.nio.channels.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.richin.system.util.Assert;

/**
 * 测试用的类还没有放到正式的帮助类中的一些方法
 * @author Administrator
 *
 */
public class IOUtils extends org.apache.commons.io.IOUtils {
	public static List<String> toList(Reader reader) {
		List<String> list = new ArrayList<String>();

		try {
			BufferedReader br = new BufferedReader(reader);

			String line = null;

			while ((line = br.readLine()) != null) {
				list.add(line);
			}

			br.close();
		} catch (IOException ioe) {
		}

		return list;
	}

	public static void closeQuietly(RandomAccessFile input) {
		try {
			if (input != null) {
				input.close();
			}
		} catch (IOException ioe) {
			// ignore
		}
	}
	  // read toByteArray
    // -----------------------------------------------------------------------
    /**
     * 以字节数组形式返回给定字节输入流中的内容。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedInputStream}。
     * </p>
     *
     * @param input 给定的字节输入流。
     * @return 给定字节输入流中内容的字节数组。
     * @throws NullPointerException 如果给定的字节输入流为 {@code null}。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO 1.1)
     */
    public static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        copy(input, output);
        return output.toByteArray();
    }

    /**
     * 用默认的字符编码，以字节数组形式返回给定字符输入流中的内容。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedReader}。
     * </p>
     *
     * @param input 给定的字符输入流。
     * @return 给定字符输入流中默认字符编码的内容字节数组。
     * @throws NullPointerException 如果给定的字符输入流为 {@code null}。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO 1.1)
     */
    public static byte[] toByteArray(Reader input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        copy(input, output);
        return output.toByteArray();
    }

    /**
     * 用给定的字符编码，以字节数组形式返回给定字符输入流中的内容。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedReader}。
     * </p>
     *
     * @param input 给定的字符输入流。
     * @param encoding 给定的字符编码名称。
     * @return 给定字符输入流中给定字符编码的内容字节数组。
     * @throws NullPointerException 如果给定的字符输入流为 {@code null}。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO 1.1)
     */
    public static byte[] toByteArray(Reader input, String encoding) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        copy(input, output, encoding);
        return output.toByteArray();
    }

    // read char[]
    // -----------------------------------------------------------------------
    /**
     * 用默认的字符编码，以字符数组形式返回给定字符输入流中的内容。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedInputStream}。
     * </p>
     *
     * @param input 给定的字节输入流。
     * @return 给定字节输入流中默认字符编码的内容字符数组。
     * @throws NullPointerException 如果给定的字节输入流为 {@code null}。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO 1.1)
     */
    public static char[] toCharArray(InputStream input) throws IOException {
        CharArrayWriter output = new CharArrayWriter();
        copy(input, output);
        return output.toCharArray();
    }

    /**
     * 用默认的字符编码，以字符数组形式返回给定字符输入流中的内容。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedInputStream}。
     * </p>
     *
     * @param input 给定的字节输入流。
     * @param encoding 给定的字符编码名称。
     * @return 给定字节输入流中默认字符编码的内容字符数组。
     * @throws NullPointerException 如果给定的字节输入流为 {@code null}。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO 1.1)
     */
    public static char[] toCharArray(InputStream input, String encoding) throws IOException {
        CharArrayWriter output = new CharArrayWriter();
        copy(input, output, encoding);
        return output.toCharArray();
    }

    /**
     * 以字符数组形式返回给定字符输入流中的内容。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedReader}。
     * </p>
     *
     * @param input 给定的字符输入流。
     * @return 给定字符输入流中的内容字符数组。
     * @throws NullPointerException 如果给定的字符输入流为 {@code null}。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO 1.1)
     */
    public static char[] toCharArray(Reader input) throws IOException {
        CharArrayWriter output = new CharArrayWriter();
        copy(input, output);
        return output.toCharArray();
    }
    // read toString
    // -----------------------------------------------------------------------
    /**
     * 用默认的字符编码，以字符串形式返回给定字节输入流中的内容。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedInputStream}。
     * </p>
     *
     * @param input 给定的字节输入流。
     * @return 给定字节输入流中的字符串内容。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO)
     */
    public static String toString(InputStream input) throws IOException {
        StringWriter sw = new StringWriter();
        copy(input, sw);
        return sw.toString();
    }

    /**
     * 用给定的字符编码，以字符串形式返回给定字节输入流中的内容。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedInputStream}。
     * </p>
     *
     * @param input 给定的字节输入流。
     * @param encoding 给定的字符编码名称。
     * @return 给定字节输入流中的指定字符编码的字符串内容。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO)
     */
    public static String toString(InputStream input, String encoding) throws IOException {
        StringWriter sw = new StringWriter();
        copy(input, sw, encoding);
        return sw.toString();
    }
    // copy from InputStream
    // -----------------------------------------------------------------------
    /**
     * 从给定的字节输入流 {@code java.io.InputStream} 中读取大量的字节到给定的字节输出流
     * {@code java.io.OutputStream} 中。该方法通常用来操作容量超过 {@code 2GB} 的读入流。
     * <p>
     * 该方法中已包含一个内部缓冲区，所以不需要使用 {@code java.io.BufferedInputStream}。
     * </p>
     *
     * @param input 一个给定的字节输入流。
     * @param output 一个给定的字节输出流。
     * @return 返回读取的字节数。
     * @throws IOException 在字节读取或输出过程中发生 {@code I/O} 错误时，抛出此异常。
     * @since IOUtils.class (Apache Commons IO 1.3)
     */
    public static long copyLarge(InputStream input, OutputStream output) throws IOException {
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        long count = 0;
        int n = 0;
        while ((n = input.read(buffer)) != -1) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
    }

    /**
     * 以字符串形式返回给定字符输入流中的内容。
     *
     * @param input 给定的字符输入流。
     * @return 给定字符输入流中的字符串内容。
     * @throws IOException 如果读入或写出过程中发生 I/O 错误。
     * @since IOUtils.class (Apache Commons IO)
     */
    public static String toString(Reader input) throws IOException {
        StringWriter sw = new StringWriter();
        copy(input, sw);
        return sw.toString();
    }

	public static void closeQuietly(InputStream input,OutputStream output) {
		try {
			if (input != null) {
				input.close();
			}
			if (output != null) {
				output.close();
			}
		} catch (IOException ioe) {
			// ignore
		}
	}

	public static void fun(File f) {
		File[] codefile = f.listFiles();
		//System.out.println(codefile);
		for (int i = 0; i < codefile.length; i++) {
			String fileName = codefile[i].getName();
			if (fileName.indexOf(".jsp") > 0) {//这是输出后缀名为.jsp的文件,不需要就去掉
				System.out.println(fileName);
			} else if (codefile[i].isDirectory()) {
				fun(codefile[i]);
			}
		}
		// fun(f);
	}

	public static <V extends InputStream> V close(V in) {
		if (in != null) {
			try {
				in.close();
			} catch (Exception e) {

			}
		}
		return null;
	}

	public static <V extends OutputStream> V close(V out) {
		if (out != null) {
			try {
				out.flush();
			} catch (Exception e) {

			}
			try {
				out.close();
			} catch (Exception e) {

			}
		}
		return null;
	}

	public static <V extends Reader> V close(V in) {
		if (in != null) {
			try {
				in.close();
			} catch (Exception e) {

			}
		}
		return null;
	}

	public static <V extends Writer> V close(V out) {
		if (out != null) {
			try {
				out.flush();
			} catch (Exception e) {

			}
			try {
				out.close();
			} catch (Exception e) {

			}
		}
		return null;
	}

	private static final int DEFAULT_BUFFER_SIZE = 8192;

	/**
	 * 从输入流读取内容, 写入到输出流中.  此方法使用大小为8192字节的默认的缓冲区.
	 *
	 * @param in 输入流
	 * @param out 输出流
	 *
	 * @throws IOException 输入输出异常
	 */
	public static void io(InputStream in, OutputStream out) throws IOException {
		io(in, out, -1);
	}

	/**
	 * 从输入流读取内容, 写入到输出流中.  使用指定大小的缓冲区.
	 *
	 * @param in 输入流
	 * @param out 输出流
	 * @param bufferSize 缓冲区大小(字节数)
	 *
	 * @throws IOException 输入输出异常
	 */
	public static void io(InputStream in, OutputStream out, int bufferSize) throws IOException {
		if (bufferSize == -1) {
			bufferSize = DEFAULT_BUFFER_SIZE;
		}

		byte[] buffer = new byte[bufferSize];
		int amount;

		while ((amount = in.read(buffer)) >= 0) {
			out.write(buffer, 0, amount);
		}
	}

	/**
	 * 从输入流读取内容, 写入到输出流中.  此方法使用大小为4096字符的默认的缓冲区.
	 *
	 * @param in 输入流
	 * @param out 输出流
	 *
	 * @throws IOException 输入输出异常
	 */
	public static void io(Reader in, Writer out) throws IOException {
		io(in, out, -1);
	}

	/**
	 * 从输入流读取内容, 写入到输出流中.  使用指定大小的缓冲区.
	 *
	 * @param in 输入流
	 * @param out 输出流
	 * @param bufferSize 缓冲区大小(字符数)
	 *
	 * @throws IOException 输入输出异常
	 */
	public static void io(Reader in, Writer out, int bufferSize) throws IOException {
		if (bufferSize == -1) {
			bufferSize = DEFAULT_BUFFER_SIZE >> 1;
		}

		char[] buffer = new char[bufferSize];
		int amount;

		while ((amount = in.read(buffer)) >= 0) {
			out.write(buffer, 0, amount);
		}
	}

	/**
	 * 取得同步化的输出流.
	 *
	 * @param out 要包裹的输出流
	 *
	 * @return 线程安全的同步化输出流
	 */
	public static OutputStream synchronizedOutputStream(OutputStream out) {
		return new SynchronizedOutputStream(out);
	}

	/**
	 * 取得同步化的输出流.
	 *
	 * @param out 要包裹的输出流
	 * @param lock 同步锁
	 *
	 * @return 线程安全的同步化输出流
	 */
	public static OutputStream synchronizedOutputStream(OutputStream out, Object lock) {
		return new SynchronizedOutputStream(out, lock);
	}

	/**
	 * 将指定输入流的所有文本全部读出到一个字符串中.
	 *
	 * @param in 要读取的输入流
	 *
	 * @return 从输入流中取得的文本
	 *
	 * @throws IOException 输入输出异常
	 */
	public static String readText(InputStream in) throws IOException {
		return readText(in, null, -1);
	}

	/**
	 * 将指定输入流的所有文本全部读出到一个字符串中.
	 *
	 * @param in 要读取的输入流
	 * @param encoding 文本编码方式
	 *
	 * @return 从输入流中取得的文本
	 *
	 * @throws IOException 输入输出异常
	 */
	public static String readText(InputStream in, String encoding) throws IOException {
		return readText(in, encoding, -1);
	}

	/**
	 * 将指定输入流的所有文本全部读出到一个字符串中.
	 *
	 * @param in 要读取的输入流
	 * @param encoding 文本编码方式
	 * @param bufferSize 缓冲区大小(字符数)
	 *
	 * @return 从输入流中取得的文本
	 *
	 * @throws IOException 输入输出异常
	 */
	public static String readText(InputStream in, String encoding, int bufferSize) throws IOException {
		Reader reader = (encoding == null) ? new InputStreamReader(in) : new InputStreamReader(in, encoding);

		return readText(reader, bufferSize);
	}

	/**
	 * 将指定<code>Reader</code>的所有文本全部读出到一个字符串中.
	 *
	 * @param reader 要读取的<code>Reader</code>
	 *
	 * @return 从<code>Reader</code>中取得的文本
	 *
	 * @throws IOException 输入输出异常
	 */
	public static String readText(Reader reader) throws IOException {
		return readText(reader, -1);
	}

	/**
	 * 将指定<code>Reader</code>的所有文本全部读出到一个字符串中.
	 *
	 * @param reader 要读取的<code>Reader</code>
	 * @param bufferSize 缓冲区的大小(字符数)
	 *
	 * @return 从<code>Reader</code>中取得的文本
	 *
	 * @throws IOException 输入输出异常
	 */
	public static String readText(Reader reader, int bufferSize) throws IOException {
		StringWriter writer = new StringWriter();

		io(reader, writer, bufferSize);
		return writer.toString();
	}

	/**
	 * 同步化的输出流包裹器.
	 */
	private static class SynchronizedOutputStream extends OutputStream {
		private OutputStream out;
		private Object lock;

		SynchronizedOutputStream(OutputStream out) {
			this(out, out);
		}

		SynchronizedOutputStream(OutputStream out, Object lock) {
			this.out = out;
			this.lock = lock;
		}

		public void write(int datum) throws IOException {
			synchronized (lock) {
				out.write(datum);
			}
		}

		public void write(byte[] data) throws IOException {
			synchronized (lock) {
				out.write(data);
			}
		}

		public void write(byte[] data, int offset, int length) throws IOException {
			synchronized (lock) {
				out.write(data, offset, length);
			}
		}

		public void flush() throws IOException {
			synchronized (lock) {
				out.flush();
			}
		}

		public void close() throws IOException {
			synchronized (lock) {
				out.close();
			}
		}
	}

	/**
	 * Get a <code>BufferedInputStream</code>.
	 */
	public final static BufferedInputStream getBufferedInputStream(InputStream in) {
		BufferedInputStream bin = null;
		if (in instanceof java.io.BufferedInputStream) {
			bin = (BufferedInputStream) in;
		} else {
			bin = new BufferedInputStream(in);
		}
		return bin;
	}

	/**
	 * Get a <code>BufferedOutputStream</code>.
	 */
	public final static BufferedOutputStream getBufferedOutputStream(OutputStream out) {
		BufferedOutputStream bout = null;
		if (out instanceof java.io.BufferedOutputStream) {
			bout = (BufferedOutputStream) out;
		} else {
			bout = new BufferedOutputStream(out);
		}
		return bout;
	}

	/**
	 * Get <code>BufferedReader</code>.
	 */
	public final static BufferedReader getBufferedReader(Reader reader) {
		BufferedReader buffered = null;
		if (reader instanceof java.io.BufferedReader) {
			buffered = (BufferedReader) reader;
		} else {
			buffered = new BufferedReader(reader);
		}
		return buffered;
	}

	/**
	 * Get <code>BufferedWriter</code>.
	 */
	public final static BufferedWriter getBufferedWriter(Writer wr) {
		BufferedWriter bw = null;
		if (wr instanceof java.io.BufferedWriter) {
			bw = (BufferedWriter) wr;
		} else {
			bw = new BufferedWriter(wr);
		}
		return bw;
	}

	/**
	 * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
	 * @param bufferSize Size of internal buffer to use.
	 */
	public final static void copy(Reader input, Writer output, int bufferSize) throws IOException {
		char buffer[] = new char[bufferSize];
		int n = 0;
		while ((n = input.read(buffer)) != -1) {
			output.write(buffer, 0, n);
		}
	}

	/**
	 * Copy chars from a <code>InputStream</code> to a <code>OutputStream</code>.
	 * @param bufferSize Size of internal buffer to use.
	 */
	public final static void copy(InputStream input, OutputStream output, int bufferSize) throws IOException {
		byte buffer[] = new byte[bufferSize];
		int n = 0;
		while ((n = input.read(buffer)) != -1) {
			output.write(buffer, 0, n);
		}
	}

	/**
	 * Read fully from reader
	 */
	public final static String readFully(Reader reader) throws IOException {
		StringWriter writer = new StringWriter();
		copy(reader, writer, 1024);
		return writer.toString();
	}

	/**
	 * Read fully from stream
	 */
	public final static String readFully(InputStream input) throws IOException {
		StringWriter writer = new StringWriter();
		InputStreamReader reader = new InputStreamReader(input);
		copy(reader, writer, 1024);
		return writer.toString();
	}

	/**
	 * Read the contents of the given URL into a byte array.
	 *
	 * @param input
	 *          the URL to read
	 * @return an array of bytes.
	 * @throws IOException
	 *           in case of I/O error
	 */
	public static byte[] read(URL input) throws IOException {
		ByteArrayOutputStream byteStream = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE);
		copy(byteStream, input);
		return byteStream.toByteArray();
	}

	/**
	 * Read the contents of the given InputStream into a byte array.
	 *
	 * @param input
	 *          the InputStream to read
	 * @return an array of bytes.
	 * @throws IOException
	 *           in case of I/O error
	 */
	public static byte[] read(InputStream source) throws IOException {
		ByteArrayOutputStream byteStream = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE);
		copy(byteStream, source);
		return byteStream.toByteArray();
	}

	/**
	 * Copy data from an {@link InputStream} to an {@link OutputStream} until an
	 * end-of-stream is reached on the source {@link InputStream}. This method
	 * does <em>not</em> attempt to close either the source or the destination
	 * stream.
	 *
	 * @param dest
	 *          destination {@link OutputStream}
	 * @param source
	 *          source {@link InputStream}
	 * @param bufSize
	 *          write buffer size
	 * @throws IOException
	 *           in case of I/O error
	 */
	public static void copy(OutputStream dest, InputStream source, int bufSize) throws IOException {
		byte[] buf = new byte[bufSize];
		int read;
		while ((read = source.read(buf)) != -1) {
			dest.write(buf, 0, read);
		}

	}

	/**
	 * Copy data from an {@link Reader} to an {@link Writer} until an
	 * end-of-stream is reached on the source {@link Reader}. This method does
	 * <em>not</em> attempt to close either the source or the destination
	 * stream.
	 *
	 * @param dest
	 *          destination {@link Writer}
	 * @param source
	 *          source {@link Reader}
	 * @param bufSize
	 *          write buffer size
	 * @throws IOException
	 *           in case of I/O error
	 */
	public static void copy(Writer dest, Reader source, int bufSize) throws IOException {
		char[] buf = new char[bufSize];
		int read;
		while ((read = source.read(buf)) != -1) {
			dest.write(buf, 0, read);
		}
	}

	/**
	 * Copy with default buffer size.
	 *
	 * @see #copy(java.io.OutputStream, java.io.InputStream)
	 * @see #DEFAULT_BUFFER_SIZE
	 */
	public static void copy(OutputStream dest, InputStream source) throws IOException {
		copy(dest, source, DEFAULT_BUFFER_SIZE);
	}

	/**
	 * Copy from {@link URL} stream.
	 *
	 * @see #copy(java.io.OutputStream, java.io.InputStream, int)
	 * @param dest
	 *          destination {@link OutputStream}
	 * @param source
	 *          source {@link URL}
	 */
	public static void copy(OutputStream dest, URL source) throws IOException {
		InputStream urlStream = source.openStream();
		copy(dest, urlStream);
		urlStream.close();
	}

	/**
	 * Write a {@link Serializable} object to an output stream using the
	 * {@link ObjectOutputStream} mechanism.
	 *
	 * @param dest
	 *          destination {@link OutputStream}
	 * @param src
	 *          source {@link Serializable}
	 * @throws IOException
	 */
	public static void write(OutputStream dest, Serializable src) throws IOException {
		ObjectOutputStream oos = new ObjectOutputStream(dest);
		oos.writeObject(src);
		oos.flush();
	}

	/**
	 * Creates an {@link InputStream} from a {@link ByteBuffer}.
	 * 
	 * @since 1.3
	 */
	public static InputStream newInputStream(final ByteBuffer buf) {
		return new InputStream() {
			public synchronized int read() throws IOException {
				if (!buf.hasRemaining()) {
					return -1;
				}
				try {
					return buf.get();
				} catch (Exception e) {
					final IOException exc = new IOException("Error while reading from ByteBuffer");
					exc.initCause(e);
					throw exc;
				}
			}

			public int read(byte[] b, int off, int len) throws IOException {
				if (!buf.hasRemaining()) {
					return -1;
				}
				final int maxLen = Math.min(len, buf.remaining());
				try {
					buf.get(b, off, maxLen);
				} catch (Exception e) {
					final IOException exc = new IOException("Error while reading from ByteBuffer");
					exc.initCause(e);
					throw exc;
				}
				return maxLen;
			}
		};
	}

	/**
	 * Creates an {@link OutputStream} from a {@link ByteBuffer}.
	 * 
	 * @since 1.3
	 */
	public static OutputStream newOutputStream(final ByteBuffer buf) {
		return new OutputStream() {
			public synchronized void write(int b) throws IOException {
				try {
					buf.put((byte) b);
				} catch (Exception e) {
					final IOException exc = new IOException("Error while writing to ByteBuffer");
					exc.initCause(e);
					throw exc;
				}
			}

			public synchronized void write(byte[] b, int off, int len) throws IOException {
				try {
					buf.put(b, off, len);
				} catch (Exception e) {
					final IOException exc = new IOException("Error while writing to ByteBuffer");
					exc.initCause(e);
					throw exc;
				}
			}
		};
	}
	/**
     * Saves the source file stream into the given file. Returns true if the process is successfull.
     * @param source
     * @param destination
     * @return
     */
    public static final boolean saveStreamToFile(InputStream source,String destination,int bufferSize){
        boolean ret = false;
	    BufferedOutputStream bos;
	    BufferedInputStream is;
	    byte[] buffer;
	    int bfrSize = 0;
	    if(source != null){
	        try {
		        is = new BufferedInputStream(source);
                //
                File f = new File(destination);
                File fp = new File(f.getParent());
                if(!fp.exists()){
                    fp.mkdirs();
                }
                //
		        bos = new BufferedOutputStream(new FileOutputStream(f));
		        while(is.available() > 0){
		            bfrSize = (is.available() > bufferSize) ? bufferSize : is.available();
		            buffer = new byte[bfrSize];
		            is.read(buffer);
		            bos.write(buffer);
		            bos.flush();
		        }
                bos.close();
                ret = true;
            }catch (Exception e) {
                e.printStackTrace();
            }
	    }
        return ret;
    }
    /**
     * Return a buffered input stream from a URL
     *
     * @param l The location
     * @return The stream buffered
     */
    public static final BufferedInputStream getBufferedInputStream(final URL l)
    {
        try
        {
            return new BufferedInputStream(l.openStream());
        }
        catch (final IOException ioe)
        {
            return null;
        }
    }
    /**
     * Return a buffered input stream from a file
     *
     * @param f The file
     * @return The stream buffered
     */
    public static final BufferedInputStream getBufferedInputStream(final File f)
    {
        try
        {
            return new BufferedInputStream(new FileInputStream(f));
        }
        catch (final IOException ioe)
        {
            return null;
        }
    }
    /**
     * Return a buffered reader from a URL
     *
     * @param l The location
     * @return The stream buffered
     */
    public static final BufferedReader getBufferedReader(final URL l)
    {
        try
        {
            return new BufferedReader(new InputStreamReader(l.openStream()));
        }
        catch (final IOException ioe)
        {
            return null;
        }
    }
    
    /**
     * Return a buffered reader from a file
     *
     * @param f The file
     * @return The stream buffered
     */
    public static final BufferedReader getBufferedReader(final File f)
    {
        try
        {
            return new BufferedReader(new FileReader(f));
        }
        catch (final IOException ioe)
        {
            return null;
        }
    }
    /**
     * Return a buffered output stream from a URL and ensure directories are created.
     *
     * @param l The location
     * @return The stream buffered
     */
    public static final BufferedOutputStream getBufferedOutputStream(final URL l)
    {
        return getBufferedOutputStream(new File(l.getFile()));
    }
    
    /**
     * Return a buffered output stream from a file and ensure directories are created.
     *
     * @param f The file
     * @return The stream buffered
     */
    public static final BufferedOutputStream getBufferedOutputStream(final File f)
    {
        try
        {
            if (f.getParentFile() != null)
            {
                f.getParentFile().mkdirs();
            }
            return new BufferedOutputStream(new FileOutputStream(f));
        }
        catch (final IOException ioe)
        {
            return null;
        }
    }
    /**
     * Return a buffered output writer from a URL and ensure directories are created.
     *
     * @param l The location
     * @return The stream buffered
     */
    public static final BufferedWriter getBufferedWriter(final URL l)
    {
        return getBufferedWriter(new File(l.getFile()));
    }
    
    /**
     * Return a buffered output writer from a file and ensure directories are created.
     *
     * @param f The file
     * @return The stream buffered
     */
    public static final BufferedWriter getBufferedWriter(final File f)
    {
        try
        {
            if (f.getParentFile() != null)
            {
                f.getParentFile().mkdirs();
            }
            return new BufferedWriter(new FileWriter(f));
        }
        catch (final IOException ioe)
        {
            return null;
        }
        
    }

    /**
     * Pass the input stream to an output stream.
     *
     * @param in  the input stream to read from
     * @param out the output stream to write to
     */
    public static void inputToOutput(InputStream in, OutputStream out)
            throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1)
            out.write(buffer, 0, read);
        in.close();
        if (!out.equals(System.out))
            out.close();
    }

    /**
     * Pass the input stream to an output stream.
     *
     * @param in  the input stream to read from
     * @param out the output stream to write to
     */
    public static void readerToOutput(Reader in, OutputStream out)
            throws IOException {
        BufferedReader reader = new BufferedReader(in);
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));

        String line;
        while ((line = reader.readLine()) != null) {
            writer.write(line);
            writer.newLine();
        }

        reader.close();
        if (!out.equals(System.out))
            writer.close();
    }

    public static ByteBuffer read(ReadableByteChannel channel) throws IOException {
        final ByteAccumulator buf = new ByteAccumulator(ByteBuffer.allocateDirect(2048));
        final ByteBuffer tempBuf = ByteBuffer.allocate(1024);

        try {
            while (channel.read(tempBuf) != -1) {
                tempBuf.flip();
                buf.append(tempBuf);
                tempBuf.clear();
            }
        } finally {
            IOUtils.close(channel);
        }

        final ByteBuffer finalBuf = buf.get();
        finalBuf.flip();
        return finalBuf;
    }


    public static void write(WritableByteChannel channel, ByteBuffer buf)
            throws IOException {
        try {
            while (buf.hasRemaining()) {
                channel.write(buf);
            }
        } finally {
            IOUtils.close(channel);
        }
    }
    /**
     * Ferme un objet implmentant l'interface {@link Closeable} sans lever
     * d'exception.
     */
    public static void close(Closeable closeable) {
        if (closeable == null) {
            return;
        }
        try {
            closeable.close();
        } catch (IOException ignore) {
        }
    }
    public static byte[] readResource(String path) throws IOException {
        return read(IOUtils.class.getResourceAsStream(path));
    }
    /**
     * Copies the InputStream into the OutputStream, until the end of the stream
     * has been reached.
     *
     * @param in the inputstream from which to read.
     * @param out the outputstream where the data is written to.
     * @param buffersize the buffer size.
     * @throws IOException if a IOError occurs.
     */
    public void copyStreams(final InputStream in, final OutputStream out, 
            final int buffersize) throws IOException {
        // create a 4kbyte buffer to read the file
        final byte[] bytes = new byte[buffersize];

        // the input stream does not supply accurate available() data
        // the zip entry does not know the size of the data
        int bytesRead = in.read(bytes);
        while (bytesRead > -1) {
            out.write(bytes, 0, bytesRead);
            bytesRead = in.read(bytes);
        }
    }
    /**
     * Copies the contents of the Reader into the Writer, until the end of the 
     * stream has been reached. This method uses a buffer of 4096 kbyte.
     *
     * @param in the reader from which to read.
     * @param out the writer where the data is written to.
     * @throws IOException if a IOError occurs.
     */
    public void copyWriter(final Reader in, final Writer out)
        throws IOException {
        copyWriter(in, out, 4096);
    }

    /**
     * Copies the contents of the Reader into the Writer, until the end of the 
     * stream has been reached.
     *
     * @param in  the reader from which to read.
     * @param out  the writer where the data is written to.
     * @param buffersize  the buffer size.
     *
     * @throws IOException if a IOError occurs.
     */
    public void copyWriter(final Reader in, final Writer out, 
            final int buffersize)
        throws IOException {
        // create a 4kbyte buffer to read the file
        final char[] bytes = new char[buffersize];

        // the input stream does not supply accurate available() data
        // the zip entry does not know the size of the data
        int bytesRead = in.read(bytes);
        while (bytesRead > -1) {
            out.write(bytes, 0, bytesRead);
            bytesRead = in.read(bytes);
        }
    }
    /**
     * Reads all bytes from a {@link Channel} until <code>EOF</code> is
     * reached.
     * 
     * @since 1.2
     */
    public static ByteBuffer read(ReadableByteChannel channel, ByteBuffer buffer)
            throws IOException {
        final ByteAccumulator acc = new ByteAccumulator();
        buffer.clear();
        while (channel.read(buffer) != -1) {
            buffer.flip();
            acc.append(buffer);
            buffer.clear();
        }

        final ByteBuffer finalBuf = acc.get();
        finalBuf.flip();

        return finalBuf;
    }
    /**
     * Reads all bytes from an {@link InputStream} until <code>EOF</code> is
     * reached.
     */
    public static byte[] read(InputStream input, int len) throws IOException {
        final ByteBuffer buf = read(Channels.newChannel(input), ByteBuffer
                .allocate(Math.max(len, 1024)));
        final byte[] data = new byte[buf.remaining()];
        assert buf.hasArray();
        System.arraycopy(buf.array(), buf.arrayOffset(), data, 0, data.length);

        return data;
    }
    /**
     * Copies all bytes from an input {@link Channel} to an output
     * {@link Channel} until <code>EOF</code> is reached. The output
     * {@link Channel} is not closed nor flushed at the end of the copy.
     * 
     * @since 1.2
     */
    public static void copy(ReadableByteChannel input,
            WritableByteChannel output, ByteBuffer buf) throws IOException {
  
        buf.clear();
        while (input.read(buf) != -1) {
            buf.flip();
            output.write(buf);

            if (buf.hasRemaining()) {
                // not all bytes were written: we'll write them in the next
                // round
                buf.compact();
            } else {
                buf.clear();
            }
        }
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		File file = new File("d:/umemo");
		fun(file);
		
	}
	public static byte[] getBytes(InputStream is) throws IOException {
		byte[] data = null;

		Collection<byte[]> chunks = new ArrayList<byte[]>();
		byte[] buffer = new byte[1024 * 1000];
		int read = -1;
		int size = 0;

		while ((read = is.read(buffer)) != -1) {
			if (read > 0) {
				byte[] chunk = new byte[read];
				System.arraycopy(buffer, 0, chunk, 0, read);
				chunks.add(chunk);
				size += chunk.length;
			}
		}

		if (size > 0) {
			ByteArrayOutputStream bos = null;
			try {
				bos = new ByteArrayOutputStream(size);
				for (Iterator<byte[]> itr = chunks.iterator(); itr.hasNext();) {
					bos.write(itr.next());
				}
				data = bos.toByteArray();
			} finally {
				if (bos != null) {
					bos.close();
				}
			}
		}
		return data;
	}
}
